#include <iostream>
#include "graph.h"

using namespace std;

template <typename T>
Graph<T>::Graph()
{
    this->nodes = {};
    this->edges = {};
    this->size = 0;
    this->id = 0;
}

template <typename T>
int Graph<T>::AddNode(T data)
{
    int id = this->id++;
    this->nodes[id] = data;
    this->size++;
    return id;
};

template <typename T>
bool Graph<T>::AddEdge(int from, int to, int weight)
{
    array<int, 2> key = {from, to};
    if (this->nodes.count(from) == 0 || this->nodes.count(to) == 0 || this->edges.count(key) > 0)
    {
        return false;
    }
    this->edges[key] = weight;
    return true;
}

template <typename T>
bool Graph<T>::RemoveNode(int id)
{
    if (this->nodes.count(id) == 0)
    {
        return false;
    }
    this->nodes.erase(id);
    this->size--;
    for (auto it = this->edges.begin(); it != this->edges.end();)
    {
        if (it->first[0] == id || it->first[1] == id)
        {
            it = this->edges.erase(it);
        }
        else
        {
            it++;
        }
    }
    return true;
}

template <typename T>
bool Graph<T>::RemoveEdge(int from, int to)
{
    array<int, 2> key = {from, to};
    if (this->edges.count(key) == 0)
    {
        return false;
    }
    this->edges.erase(key);
    return true;
}

template <typename T>
bool Graph<T>::HasEdge(int from, int to) const
{
    array<int, 2> key = {from, to};
    return this->edges.count(key) > 0;
}

template <typename T>
tuple<bool, T> Graph<T>::GetNode(int id)
{
    bool exist = this->nodes.count(id) > 0;
    T data;
    if (exist)
    {
        data = this->nodes[id];
    }
    return make_tuple(exist, data);
}

template <typename T>
int Graph<T>::Size() const
{
    return this->size;
}

int main()
{
    // 创建一个Graph<int>类型的对象
    Graph<int> graph;

    // 添加节点
    int node1 = graph.AddNode(5);
    int node2 = graph.AddNode(10);

    // 添加边
    graph.AddEdge(node1, node2, 7);

    // 验证是否存在特定边和节点
    bool hasEdge = graph.HasEdge(node1, node2);
    tuple<bool, int> nodeData = graph.GetNode(node1);
    int graphSize = graph.Size();

    // 输出验证结果
    cout << "Graph Size: " << graphSize << endl;
    cout << "Does the graph have an edge between node1 and node2? " << (hasEdge ? "Yes" : "No") << endl;
    cout << "Data of node1: " << (get<0>(nodeData) ? to_string(get<1>(nodeData)) : "Node not found") << endl;

    // 移除边和节点
    bool removedEdge = graph.RemoveEdge(node1, node2);
    bool removedNode = graph.RemoveNode(node1);

    // 输出移除结果
    cout << "Removed edge between node1 and node2? " << (removedEdge ? "Yes" : "No") << endl;
    cout << "Removed node1? " << (removedNode ? "Yes" : "No") << endl;

    return 0;
}